﻿using AntdUI;
using CKS.Core.Framework;
using ImportPlcPointPosition.Utils;
using Mapster;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace ImportPlcPointPosition.Controls
{
    public class BaseUserControl:UserControl
    {

        /// <summary>
        /// 展开PointData
        /// </summary>
        /// <returns></returns>
        public List<ImportData> PointDataToList(BindingList<ImportData> PointDatas)
        {

            var all = new List<ImportData>();
            try
            {
                var lst = new List<ImportData>();
                var child = PointDatas.ToList();
                int maxorder = 0;
                lst = DataPositionTableControl.BuildDataView(all, child, ref maxorder);

                return lst;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        /*
         精度：10 ，代表需要乘以10再除以10，
         计算Lenth时 先乘以10 
         

         */

        public decimal GetVariableOffset(ImportData data)
        {
            switch (data.DataType.ToLower())
            {
                case "struct":
                    data.ParseType = "struct";
                    return 0;
                case "int":
                    data.ParseType = "int16";
                    return 2;
                case "word":
                    data.ParseType = "word";
                    return 2;
               
                case "dint":
                    data.ParseType = "int32";
                    return 4;
                case "bool":  //不支持bool，连续bool的偏移量示例 200.0，200.1
                    data.ParseType = "bool";
                    return 0.1m;
                case "string":
                    data.ParseType = "string";
                    return 256;
                case "real":
                    data.ParseType = "float";
                    return 4;
                case "lreal":
                    data.ParseType = "double";
                    return 8;
                case "byte":
                    data.ParseType = "byte";
                    return 1;
                case "char":
                    data.ParseType = "char";
                    return 1;
                case "dt":
                    data.ParseType = "dt";
                    return 8;
                case "dtl":
                    data.ParseType = "dtl"; 
                    return 12;
                default:
                    var dataType = data.DataType.ToLower();
                    if (dataType.StartsWith("string["))
                    {
                        data.ParseType = "string";
                        return Regex.Match(dataType, "[0-9]+").Value.ObjToInt() + 2;
                    }
                    if(dataType.StartsWith("array[") && dataType.Contains("of"))
                    {
                        //Array[0..63] of Word
                       // Debug.WriteLine(dataType);
                        if (dataType.Contains("string"))
                        {
                        }
                        data.ParseType = data.DataType;
                        var matches =Regex.Matches(dataType, "[0-9]+");
                        if(matches.Count == 2)
                        {
                           var Start = matches[0].Value.ObjToInt();
                            var End = matches[1].Value.ObjToInt();
                            decimal sizelenth = End - Start + 1;

                            var arrayType = dataType.Split(' ')[2];

                          
                            sizelenth = arrayType switch
                            {
                                "byte" => sizelenth,
                                "bool" => GetBoolLenth(sizelenth),
                                "int" => sizelenth * 2,
                                "word" => sizelenth * 2,
                                "dword" => sizelenth * 4, //uint
                                "dint" => sizelenth * 4,
                                "real" => sizelenth * 4,
                                "lreal" => sizelenth * 8,
                                "dt" => sizelenth * 8,
                                "dtl" => sizelenth * 12,
                                _ => sizelenth
                            };
                            
                            //


                            //数组需要补1到2个字节的偏移长度，必须是偶数
                            if (sizelenth % 2 != 0)
                                sizelenth++;
                            return sizelenth;
                        }
                        else if(matches.Count == 3 && dataType.Contains("of string"))
                        {
                            //字符串数组
                            var Start = matches[0].Value.ObjToInt();
                            var End = matches[1].Value.ObjToInt();
                            decimal sizelenth = End - Start + 1;
                            var arrayType = dataType.Split(' ')[2];

                            sizelenth = sizelenth * (matches[2].Value.ObjToInt()+2);
                            if (sizelenth % 2 != 0)
                                sizelenth++;
                            return sizelenth;
                        }


                        return Regex.Match(dataType, "[0-9]+").Value.ObjToInt() + 2;
                    }

                    throw new NotImplementedException($"暂未支持类型 {dataType}");

            }
            //  数据类型：int\bool\string[20]\real\lreal
        }


        public decimal GetTypeOffset(string ParseType)
        {
           var   offset = ParseType switch
            {
                "byte" =>1,
                "int" => 2,
                "word" =>  2,
                "dword" =>  4, //uint
                "dint" => 4,
                "real" => 4,
                "lreal" =>  8,
                "dtl" => 12,
                "dt"=>8,
                "bool"=>0.1m,
                _ => 1
            };

            if(offset== 0 && ParseType.Contains("string"))
            {
              return  Regex.Match(ParseType, "[0-9]+").Value.ObjToInt() + 2;
            }




            return offset;
        }

        public bool IsArrayType(string ArrayType,out int arrayLenth,out string ParseType)
        {
            ParseType = "";
            arrayLenth = 0;
            var dataType = ArrayType.ToLower();
            if (dataType.StartsWith("array[") && dataType.Contains("of"))
            {
                //Array[0..63] of Word
          
                var matches = Regex.Matches(dataType, "[0-9]+");
                if (matches.Count == 2)
                {
                    var Start = matches[0].Value.ObjToInt();
                    var End = matches[1].Value.ObjToInt();
                    decimal sizelenth = End - Start + 1;
                    arrayLenth = (int)sizelenth;
                    var arrayType = dataType.Split(' ')[2];
                    sizelenth = arrayType switch
                    {
                        "bool" => GetBoolLenth(sizelenth),
                        "int" => sizelenth * 2,
                        "word" => sizelenth * 2,
                        "dword" => sizelenth * 4, //uint
                        "dint" => sizelenth * 4,
                        "real" => sizelenth * 4,
                        "lreal" => sizelenth * 8,
                        "dt" => sizelenth * 8,
                        "dtl" => sizelenth * 12,
                        _ => sizelenth
                    };
                    ParseType = arrayType;
                    //
                  
                    //
                    return true;
                }
                else if (matches.Count == 3 && dataType.Contains("of string"))
                {
                    var arrayType = dataType.Split(' ')[2];
                    ParseType = arrayType;
                    var Start = matches[0].Value.ObjToInt();
                    var End = matches[1].Value.ObjToInt();
                    decimal sizelenth = End - Start + 1;
                    arrayLenth = (int)sizelenth;

                    return true;
                }



            }
            return false;
        }


        private decimal GetBoolLenth(decimal sizelenth)
        {
           int d = (int)(sizelenth / 8);
            var yu = sizelenth  % 8;
            if ( yu == 0)
                return d;
            return d + (yu /10) ;
        }

        public void ConvertToS7Type(ImportData data)
        {
            switch (data.ParseType)
            {
                case "struct":
                    data.DataType = "Struct";
                    break;
                case "int16":
                    data.DataType = "Int";
                    break;
                case "int32":
                    data.DataType = "DInt";
                    break;
                case "bool":
                    data.DataType = "Bool";
                    break;
                case "float":
                    data.DataType = "Real";
                    break;
                case "double":
                    data.DataType = "LReal";
                    break;
                case "dt":
                    data.DataType = "DT";
                    break;
                case "dtl":
                    data.DataType = "DTL";
                    break;
                case "string":
                    data.DataType = $"string[{data.ByteLength - 2}]";
                    break;
                case "array":
                    data.DataType = $"array[{data.ByteLength - 2}]";
                    data.Operate = null;
                    break;
                default:
                    data.DataType = data.ParseType; //数据库只存了ParseType 
                    break;
            }
        }

        public void MessageInfo(string msg)
        {
            try
            {
                AntdUI.Message.info(App.MainLayout, msg, autoClose: 2);
            }
            catch (Exception)
            {

            }
        }
        public void MessageError(string msg)
        {
            AntdUI.Message.error(App.MainLayout, msg, autoClose: 2);
        }
        public void MessageBoxShow(string message, TType type = TType.Info)
        {
            try
            {
                AntdUI.Modal.open(new AntdUI.Modal.Config(this.FindForm(), "消息", message)
                {
                    Icon = type,
                    //内边距
                    Padding = new Size(24, 20),
                    OkText = "确认",
                    CancelText = null,
                });
            }
            catch (Exception)
            {

            }
        }

        public DialogResult MessageBoxWarn(string title,string message)
        {
            var result = Modal.open(this.FindForm(), title, message, TType.Warn);
            return result;
        }

        public virtual void ReflushPage()
        {
        }
    }
}
